﻿#if UNITY_2019_1_OR_NEWER

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
using UnityEngine.Profiling;
using USArray;
using USArray.Test;

public class TestUnity : MonoBehaviour
{
    List<string> infos;

    // Start is called before the first frame update
    void Start()
    {
        infos = new List<string>();
        TestPool.LogAction = (txt) =>
        {
            infos.Add(txt);
        };
        TestPool.LogAction("--init test.");
        var ngroups = new List<string>();
        setgroup = 0;
        foreach (var group in TestPool.testItems)
        {
            ngroups.Add(group.Key);
        }
        groups = ngroups.ToArray();

        var str = "";
        str += "1";
        var str2 = new string('a', 1);

        unsafe
        {
            infos.Add(USArray.UnsafePtrTool.GetStringHeader(str)->ToString());
            infos.Add(USArray.UnsafePtrTool.GetStringHeader(str2)->ToString());
            infos.Add(USArray.StringNoGC.strHeaderDef.ToString());
        }
    }

    // Update is called once per frame
    void Update()
    {

    }
    private void LateUpdate()
    {
        USArray.UnsafePtrTool.ResetTempAlloc();
    }
    int setgroup = 0;
    string[] groups;
    List<ArrayNoGC<byte>> memes = new List<ArrayNoGC<byte>>();
    List<NativeArray<byte>> memes2 = new List<NativeArray<byte>>();
    private void OnGUI()
    {
#if UNITY_EDITOR
        GUIUtility.ScaleAroundPivot(new Vector2(1.5f, 1.5f), Vector2.zero);
#else
        GUIUtility.ScaleAroundPivot(new Vector2(3, 3), Vector2.zero);
#endif
        GUILayout.Label("<NoGC Test.>");
        setgroup = GUILayout.Toolbar(setgroup, groups);
        var pickgroup = TestPool.testItems[groups[setgroup]];
        GUILayout.Label("====Group:" + groups[setgroup] + " itemcount=" + pickgroup.Count);


        foreach (var v in pickgroup)
        {
            var text = "Test:" + v.Name;
            if (v.DefaultCount > 1)
                text += " Count=" + v.DefaultCount;
            if (GUILayout.Button(text))
            {
                DoTest(v);
            }
        }

        GUILayout.Label("==gen mem count=" + memes.Count);
        unsafe
        {
            if (GUILayout.Button("Gen 5GB persist"))
            {
                infos.Clear();

                for (var i = 0; i < 5; i++)
                {
                    var nogc = ArrayNoGC<byte>.Create(1000 * 1024 * 1024, false,true);

                    memes.Add(nogc);
                    var log = "ptr=" + ((IntPtr)nogc.HeadPtr).ToString("X16");
                    if (i > 0)
                        log += " size=" + ((long)nogc.HeadPtr - (long)memes[i - 1].HeadPtr).ToString();
                    infos.Add(log);
                    //var n = new NativeArray<byte>(1000 * 1024 * 1024, Allocator.Persistent);
                    //memes2.Add(n);
                }

            }
            if (GUILayout.Button("Gen 5GB temp"))
            {
                infos.Clear();

                for (var i = 0; i < 5; i++)
                {
                    var nogc = ArrayNoGC<byte>.Create(1000 * 1024 * 1024, true, true);
                    memes.Add(nogc);
                    var log = "ptr=" + ((IntPtr)nogc.HeadPtr).ToString("X16");
                    if (i > 0)
                        log += " size=" + ((long)nogc.HeadPtr - (long)memes[i - 1].HeadPtr).ToString();
                    infos.Add(log);
                    //var n = new NativeArray<byte>(1000 * 1024 * 1024, Allocator.Temp);
                    //memes2.Add(n);
                }
            }
        }
        if (GUILayout.Button("Free persist"))
        {
            infos.Clear();

            foreach (var m in memes)
            {
                m.Free();
            }
            memes.Clear();
            foreach (var m in memes2)
            {
                m.Dispose();
            }
            memes2.Clear();
        }
        GUILayout.Label("Mem=" + (Profiler.maxUsedMemory / 1024 / 1024).ToString() + "MB");
        foreach (var l in infos)
        {
            GUILayout.Label(l);
        }
    }
    void DoTest(TestItem item, int count = -1)
    {
        infos.Clear();
        if (count < 0) count = item.DefaultCount;


        infos.Add("DoTest:" + item.Name + "count=" + count);
        item.InitTest(count);

        var m1 = GC.GetTotalMemory(true);
        var time = DateTime.Now;
        for (var i = 0; i < count; i++)
        {
            item.DoTest(i);
        }
        var time2 = DateTime.Now;
        item.EndTest();

        infos.Add("Exe time=" + (time2 - time).TotalSeconds);
        var m2 = GC.GetTotalMemory(false);
        infos.Add("Exe gc=" + TestPool.GetSizeStr(m2 - m1));
    }
}
#endif